use std::io;

fn main() {
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;
    println!("ip address {:?} {:?}", four, six);

    route(IpAddrKind::V4);
    route(IpAddrKind::V6);

    let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
    };

    let loopback = IpAddr {
        kind: IpAddrKind::V6,
        address: String::from("::1"),
    };
    println!("ip address {:?} {:?}", home, loopback);

    let home1 = IpAddrKindWithAddress::V4(String::from("127.0.0.1"));
    let loopback1 = IpAddrKindWithAddress::V6(String::from("::1"));
    println!("ip address {:?} {:?}", home1, loopback1);

    let quit = Message::Quit;
    quit.call();
    let write = Message::Write(String::from("I will write something later..."));
    write.call();
    let red = Message::ChangeColor(255, 0, 0);
    red.call();
    let msg = Message::Move { x: 1, y: 3 };
    msg.call();

    let some_number = Some(5);
    let some_char = Some('e');
    let absent_number: Option<i32> = None;

    // let x: i8 = 5;
    // let y: Option<i8> = Some(5);
    // let sum = x + y;

    println!(
        "1 Penny, 2 Nickel, 3 Dime and 4 Quarter is {} cents",
        value_in_cents(Coin::Penny)
            + value_in_cents(Coin::Nickel) * 2
            + value_in_cents(Coin::Dime) * 3
            + value_in_cents(Coin::Quarter(UsState::Alaska)) * 4
    );

    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);


    loop {
        let mut guess = String::new();
        io::stdin()
            .read_line(&mut guess)
            .expect("Failed to read line");
        let guess: u32 = match guess.trim().parse() {
            Ok(num) => num,
            Err(msg) => {
                println!("{msg}");
                continue;
            }
        };
        match guess {
            1 => println!("you enter 1!"),
            _ => println!("you enter, I don't care the detail"),
            // will raise compiler warning
            other => println!("you enter other: {}", other),
        }
    }

}

#[derive(Debug)]
enum IpAddrKind {
    V4,
    V6,
}

#[derive(Debug)]
struct IpAddr {
    kind: IpAddrKind,
    address: String,
}

#[derive(Debug)]
enum IpAddrKindWithAddress {
    V4(String),
    V6(String),
}

fn route(ip_kind: IpAddrKind) {}

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}

impl Message {
    fn call(&self) {
        match &self {
            Self::Quit => println!("Ready? I will quit this mechine, 3,2,1..."),
            Self::Move{x, y} => println!("I will move to ({}, {})", x, y),
            Self::Write(msg) => println!("I am an writer, writing '{}'  now", msg),
            Self::ChangeColor(r,g,b) => println!("I want to print world to ({}, {}, {})", r, g, b),
        }
        println!("yes! yes!, I did known how to fetch data now.");
    }
}

#[derive(Debug)] // 这样可以立刻看到州的名称
enum UsState {
    Alabama,
    Alaska,
    // --snip--
}

enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
}

fn value_in_cents(coin: Coin) -> u8 {
    match coin {
        Coin::Penny => 1,
        Coin::Nickel => 5,
        Coin::Dime => 15,
        Coin::Quarter(state) => {
            println!("State quarter from {:?}!", state);
            25
        }
    }
}

fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}